/**
 * 
 * 如果您不清楚本类的具体实现，状态管理，请不要修改代码，否则可能引起未知错误
 * 
 * 解决获取服务列表函数调用失败的方案：
 * 1.正常流程获取
 * 2.正常流程获取失败后，重新连接一次,延迟10秒(数据库可配置)再次获取
 * 3.重新连接后仍没有获取成功，则根据数据库配置的桩的uuid直接进行操作;失败则记录日志
 * 4.获取服务数据丢包处理；在1秒(数据库可配置)内没有获得完成数据包，认为丢包，则重新发送指令获取数据;
 *   只对85,95命令做重试操作
 */

import EncryptUtil from '../utils/EncryptUtil';
import CRC16 from '../utils/CRC16';
import AESUtil from '../utils/aes-util';
import util from '../utils/util';

var Base64 = require('base64.js');

var a = getApp(), s = 3, c = 500, r = null, openAdapterCount = 3, openAdapterTime = 500;

var Status = {
  normal: 'normal', //初始状态
  appVersionNotSupported: 'appVersionNotSupported', //当前客户端版本不支持小程序蓝牙
  adapterOpening: 'adapterOpening', //蓝牙适配器正在打开
  adaperOpenSuccess: 'adaperOpenSuccess', //蓝牙适配器打开成功    
  adaperOpenFail: 'adaperOpenFail', //蓝牙适配器打开失败
  adapterCloseing: 'adapterCloseing', //蓝牙适配器正在关闭
  adaperCloseSuccess: 'adaperCloseSuccess', //蓝牙适配器关闭成功    
  adaperCloseFail: 'adaperCloseFail', //蓝牙适配器关闭失败
  bleIsClosed: 'bleIsClosed', //手机蓝牙已关闭（连接设备时回调一次）
  bleIsOpened: 'bleIsOpened', //手机蓝牙已打开（连接设备时回调一次）
  bleClosed: 'bleClosed', //手机蓝牙已关闭（状态动态变化）
  bleOpened: 'bleOpened', //手机蓝牙已打开（状态动态变化）
  bleScaning: 'bleScaning', //扫描蓝牙设备中
  bleScanStart: 'bleScanStart', //开始扫描蓝牙设备
  bleScanStop: 'bleScanStop', //停止扫描蓝牙设备
  bleScanFail: 'bleScanFail', //扫描蓝牙设备失败
  bleConnectSuccess: 'bleConnectSuccess', //连接蓝牙设备成功
  bleConnectFail: 'bleConnectFail', //连接蓝牙设备失败
  bleDisconnected: 'bleDisconnected', //当前连接的蓝牙设备异常断开
  bleReConnected: 'bleReConnected', //当前连接的蓝牙设备恢复连接
  bleNotSupportWXService: 'bleNotSupportWXService', //设备不支持微信协议服务
  bleSupportWXService: 'bleSupportWXService', //设备已支持微信协议服务
  bleNotSupportWXCharacteristic: 'bleNotSupportWXCharacteristic', //设备不支持微信协议特征
  bleSupportWXCharacteristic: 'bleSupportWXCharacteristic', //设备已支持微信协议特征
  bleReceiveData: 'bleReceiveData', //设备开始接收数据
  bleConnectTimeout: 'bleConnectTimeout', //连接设备超时
  bleReceiveAuthData: 'bleReceiveAuthData', //接收请求授权数据状态
  bleReceiveInitData: 'bleReceiveInitData', //接收请求初始化数据状态
  bleReceiveBaseData: 'bleReceiveBaseData', //接收普通数据状态
  bleInitSuccess: 'bleInitSuccess', //设备连接成功（95指令已发送并解析成功），可以发送85指令了
  ble85Back1Timeout: 'ble85Back1Timeout',//85回执1超时
  ble85Back2Timeout: 'ble85Back2Timeout',//85回执2超时
  bleSend85Timeout: 'bleSend85Timeout', //发送85超时
  bleSend95Timeout: 'bleSend95Timeout', //发送95超时
  bleSend98Timeout: 'bleSend98Timeout', //发送95超时
  bleSendB0Timeout: 'bleSendB0Timeout', //发送B0超时
  bleSendBaseTimeout: 'bleSendBaseTimeout', //发送Base超时
  ble85Data: 'ble85Data', //已收到85数据
  ble95Data: 'ble95Data', //已收到95数据
  ble98Data: 'ble98Data', //已收到95数据
  ble88Data: 'ble88Data', //已收到95数据
  ble01Data: 'ble01Data', //已收到01数据，即随机数数据
}

var _ConnectTimeout = null //连接超时
var _ConnectTimeoutSize = 25 //连接超时时间（单位秒）
var _CreateConnectionTimeoutSize = 5000// 创建连接的api超时时间单位毫秒

var directConTimeoutSeconds = 15;//直连连接超时
var timer_directCon_seconds = null;

var _adapterFailTimeSize = 5 //初始化蓝牙适配器超时未执行
var _adapterFailTimer = null //定时器

var _noLocationAuthTimeSize = 10 //无位置授权的超时时间
var _noLocationAuthFlg = true //默认无位置权限，搜索到蓝牙设备后设置为false（有位置权限）
var _noLocationAuthTimer = null //定时器

var _SendCommandTimeout = null //发送指令超时（指令发送成功，并收到设备的指令响应数据，否则超时）
var _SendCommandTimeoutSize = 5 //发送指令超时时间（单位秒）
var _85Back1TimeoutSize = 6 //85第1次回执超时时间
var _85Back1Timeout = null
var _85Back2TimeoutSize = 20 //85第2次回执超时时间
var _85Back2Timeout = null

var _IsScaning = false //是否正在搜索设备
var _Status = Status.normal //当前状态
var _DeviceName = null //当前请求连接的设备名称
var _Callback = null //状态监听回调
var _ErrorLog = null //错误日志记录回调
var _ConnectLog = null //蓝牙连接日志记录回调
var _Device = null //当前请求连接的设备对象
var _scanBoxFlg = false; //true只扫描不连接
var _WXServiceUUID = null //微信协议服务的UUID
var _WXIndicateUUID = null //微信协议Indicate特征的UUID
var _WXWriteUUID = null //微信协议Write特征的UUID
var _WXReadUUID = null //微信协议Read特征的UUID
var _RetryCount = 0 //第几次重新连接设备
var _AuthString = null //设备发来的完整授权数据
var _AuthMD5 = null //授权数据中的MD5值大写，md5（deviceType + deviceId）
var _AuthSize = 0 //完整授权数据长度
var _InitString = null //设备发来的完整初始化数据
var _InitSize = 0 //完整初始化数据长度
var _RandomNumKey = '';//新固件驱动上传的随机数
var _Version = '01';//驱动协议
var _DataString = null //设备发来的普通数据
var _DataSize = 0 //普通数据长度
var _IsBLEOpened = false //当前手机蓝牙是否已打开
var _Data85 = null //解析后的85数据
var _Data88 = null //解析后的85数据
var _Data95 = null //解析后的95数据
var _Data98 = null //解析后的95数据
var _IsFirstConnected = false //是否已经首次连接成功过
var _ServerConfigInfo = {
  connectDelayed: {
    openBluetoothAdapter: 100,
    startBluetoothDevicesDiscovery: 300,
    getBLEDeviceServices: 300,
    getBLEDeviceCharacteristics: 1500,
    failGetBLEDeviceServices: 300,
    failGetBLEDeviceCharacteristics: 1000,
    writeData: 100
  }
}; //服务配置信息

var _serviceUUID = ''
var _fec7 = ''
var _fec8 = ''
var _fec9 = ''
var _CollectionServiceInfo = null; //收集桩的服务信息

var _getBLEDeviceServicesDelayTime = 10000 //重新连接后再次获取服务列表的延迟时间
var _getBLEDeviceServiesRetryConCount = 0 //获取服务列表重连次数
var _reqId = null;
var _EncryptValue = null
var _TimeBytes = null
var _that = null;

//是否中转85开锁指令为88开锁指令
var _transferOpenLockCmd = false
//硬件软件驱动版本号
var _driverVersion = null
var _BaseDataCallBack = null
//接收到的广播数据
var broadcastDevList = {};
//接收到的广播数据缓存
var broadcastDevListCache = {};
var _allowDuplicatesKey = true;//是否允许重复上报同一设备。如果允许重复上报，则 wx.onBlueToothDeviceFound 方法会多次上报同一设备，但是 RSSI 值会有不同。

function setServerConfigInfo(config) {

  console.log("【设置服务器配置信息】", config)

  if (config != null && config != undefined) {
    _ServerConfigInfo = config
    if (config.connectTimeOut) {
      _ConnectTimeoutSize = config.connectTimeOut
      //给获取服务列表延迟时间赋值
      _getBLEDeviceServicesDelayTime = _ServerConfigInfo.connectDelayed.reGetBLEDeviceServices
    }
  }
}

//设置归位桩的服务id信息
function setHomingDeviceServiceInfo(uuid, fec7, fec8, fec9) {

  console.log("【设置设备蓝牙服务信息】", uuid, fec7, fec8, fec9)

  _serviceUUID = uuid
  _fec7 = fec7
  _fec8 = fec8
  _fec9 = fec9

}
//设置连接超时时间
function setConnectiTimeOut(timeout) {

  console.log("【设置设备连接超时时间】", timeout)

  _ConnectTimeoutSize = timeout
}

//状态变化
function statusChanged(status) {

  console.log("【蓝牙管理器状态变化】", status, _Data85, _Callback)

  if (_Status == Status.bleConnectTimeout) {
    console.log("【蓝牙连接失败】设备连接超时...")
    _IsFirstConnected = true
  }

  if (status == Status.bleInitSuccess ||
    status == Status.appVersionNotSupported ||
    status == Status.bleIsClosed ||
    status == Status.bleClosed ||
    status == Status.adaperOpenFail ||
    status == Status.bleNotSupportWXService ||
    status == Status.bleNotSupportWXCharacteristic) {
    stopTimeout()
  }

  if (status == Status.ble85Data ||
    status == Status.ble95Data || status == Status.ble98Data || status == Status.ble88Data) {
    stopTimeout()
    stopSendCommandTimeout()
  }
  if (status == Status.ble85Data || status == Status.ble88Data) {
    stop85Back1Timeout()
    if (_Data85 && _Data85.isNew === 2 && _Data85.backSeq == 2) {
      stop85Back2Timeout()
    }
  }

  _Status = status

  if (status == Status.ble88Data && _Callback != null) {
    statusChanged(Status.bleReceiveData)
    let data88 = _Data88;
    _Callback(status, data88);
    _Data88 = '';
  } else if (status == Status.ble85Data && _Callback != null) {
    statusChanged(Status.bleReceiveData)
    _Callback(status, _Data85)
  } else if (status == Status.ble95Data && _Callback != null) {
    statusChanged(Status.bleReceiveData)
    _Callback(status, _Data95)
  } else if (status == Status.ble98Data && _Callback != null) {
    statusChanged(Status.bleReceiveData)
    _Callback(status, _Data98)
  } else if (status == Status.ble01Data && _Callback != null) {
    //停止连接超时的计时
    stopTimeout();
    statusChanged(Status.bleReceiveData)
    _Callback(status, _RandomNumKey)
  } else if (_Callback != null) {
    _Callback(status, null)
  }

}

//重置状态
function reset(callback) {
  if (_Device != null) {
    //尝试一次断开当前已连接的设备
    let devName = _Device.name;
    console.log("【正在尝试断开设备】" + devName)

    wx.closeBLEConnection({
      deviceId: _Device.deviceId,
      success: function (res) {

        console.log("【断开设备成功】", res)

        resetParams(callback)
      },
      fail: function (res) {
        console.error("【error】【wx.closeBLEConnection】【断开设备失败】" + devName, res)

        resetParams(callback)
      }
    })
  } else {
    resetParams(callback)
  }
}

//启动超时机制 目前只有旧连接在用，但是线上已经没有旧连接了，此处更改此函数
function startTimeout() {
  console.log("【开启蓝牙连接超时机制】", _ConnectTimeoutSize)

  stopTimeout()

  _ConnectTimeout = setTimeout(function () {
    showDialog("bleConnectTimeout", Status.bleConnectTimeout, function () { });
    console.error("【error】【bleConnectTimeout】【蓝牙连接失败】设备连接超时...")

  }, _ConnectTimeoutSize * 1000)
}

//停止超时机制
function stopTimeout() {
  if (_ConnectTimeout != null) {
    clearTimeout(_ConnectTimeout)
    console.log("【关闭蓝牙连接超时机制】")
  }
  _ConnectTimeout = null
}

//启动蓝牙适配器初始化超时机制
function startOpenAdapterTimeout() {
  _that = _that ? _that : getApp().globalData._that

  stopOpenAdapterTimeout()

  console.log("启动蓝牙适配器初始化超时机制")

  _adapterFailTimer = setTimeout(() => {
    stopTimeout();
    stopLocationAuthTimeout();
    console.error("初始化蓝牙适配器超时未执行");
    showDialog("openAdapterTimeout", Status.bleConnectTimeout, function () { });
  }, 1000 * _adapterFailTimeSize)
}

//关闭适配器初始化超时机制
function stopOpenAdapterTimeout() {
  if (_adapterFailTimer != null) {
    clearTimeout(_adapterFailTimer)
    console.log("关闭适配器初始化超时机制")
  }
  _adapterFailTimer = null
}

//启动位置权限超时机制
function startLocationAuthTimeout() {
  _that = _that ? _that : getApp().globalData._that

  stopLocationAuthTimeout()

  console.log("启动位置授权超时机制")

  _noLocationAuthTimer = setTimeout(() => {
    stopTimeout();
    stopOpenAdapterTimeout()
    console.error("蓝牙搜索 超时未收到");
    showDialog("noDevicesFound", Status.bleConnectTimeout, function () { });
  }, 1000 * _noLocationAuthTimeSize)
}

//关闭位置权限超时机制
function stopLocationAuthTimeout() {
  if (_noLocationAuthTimer != null) {
    clearTimeout(_noLocationAuthTimer)
    console.log("关闭位置授权超时机制")
  }
  _noLocationAuthTimer = null
}

//启动发送指令超时机制
function startSendCommandTimeout(status) {

  console.log("【开启发送指令超时机制】", status)

  stopSendCommandTimeout()
  _SendCommandTimeout = setTimeout(function () {
    statusChanged(status)

    console.error("【error】【sendCommandTimeout】【发送指令超时】", status)

    thisDisconnect('发送指令超时：' + status)

  }, _SendCommandTimeoutSize * 1000)
}

//停止发送指令超时机制
function stopSendCommandTimeout() {
  if (_SendCommandTimeout != null) {
    clearTimeout(_SendCommandTimeout)
    console.log("【关闭发送指令超时机制】")
  }
  _SendCommandTimeout = null
}



//启动85回执1超时机制
function start85Back1Timeout(status) {

  console.log("【开启85回执1超时机制】", status)
  stop85Back1Timeout()

  _85Back1Timeout = setTimeout(function () {
    statusChanged(status)
    stop85Back2Timeout()

    console.error("【error】【85Back1Timeout】【85回执1超时】", status)

    // thisDisconnect('85回执1超时：' + status)//85回执超时不断开连接，因为可能需要重发85

  }, _85Back1TimeoutSize * 1000)
}

//停止85回执1超时机制
function stop85Back1Timeout() {
  if (_85Back1Timeout != null) {
    clearTimeout(_85Back1Timeout)
    console.log("【关闭85回执1超时机制】")
  }
  _85Back1Timeout = null
}

//启动85回执2超时机制
function start85Back2Timeout(status) {

  console.log("【开启85回执2超时机制】", status)
  stop85Back2Timeout()

  _85Back2Timeout = setTimeout(function () {
    statusChanged(status)
    console.error("【error】【85Back2Timeout】【85回执2超时】", status)

    // thisDisconnect('85回执2超时：' + status)//85回执超时不断开连接，因为可能需要重发85

  }, _85Back2TimeoutSize * 1000)
}

//停止85回执2超时机制
function stop85Back2Timeout() {
  if (_85Back2Timeout != null) {
    clearTimeout(_85Back2Timeout)
    console.log("【关闭85回执2超时机制】")
  }
  _85Back2Timeout = null
}


//收集设备服务信息
function setCollectionServiceData(callback) {
  console.log("【设置收集设备服务信息】")
  _CollectionServiceInfo = callback
}
//设置错误日志记录回调
function setErrorCallback(callback) {
  console.log("【设置错误日志记录回调】")
  _ErrorLog = callback
}

//设置错误日志记录回调
function setConnectLogCall(callback) {
  console.log("【设置连接错误日志记录回调】")
  _ConnectLog = callback
}

//重置具体参数
function resetParams(callback) {

  console.log("【重置默认参数】", callback == null ? 'callback is null' : 'callback not null')

  _IsScaning = false //是否正在搜索设备
  _Status = Status.normal //当前状态
  _DeviceName = null //当前请求连接的设备名称
  _Callback = null //状态监听回调
  _Device = null //当前请求连接的设备对象
  _scanBoxFlg = false;
  _WXServiceUUID = null //微信协议服务的UUID
  _WXIndicateUUID = null //微信协议Indicate特征的UUID
  _WXWriteUUID = null //微信协议Write特征的UUID
  _WXReadUUID = null //微信协议Read特征的UUID
  _AuthString = null //完整授权数据
  _AuthMD5 = null //授权数据中的MD5值大写，md5（deviceType + deviceId）
  _AuthSize = 0 //完整授权数据长度
  _InitString = null //设备发来的完整初始化数据
  _InitSize = 0 //完整初始化数据长度
  _RandomNumKey = '';//新版驱动收取的随机数
  _Version = '01';//驱动协议
  _DataString = null //设备发来的普通数据
  _DataSize = 0 //普通数据长度
  _IsBLEOpened = false //当前手机蓝牙是否已打开
  _Data85 = null //解析后的85数据
  _Data88 = null //解析后的85数据
  _Data95 = null //解析后的95数据
  //是否中转85开锁指令为88开锁指令 2019-08-07 16:57直接是用88进行开锁
  _transferOpenLockCmd = true
  _driverVersion = null
  _BaseDataCallBack = null

  callback()

}

//尝试重新连接设备
function retryConnect(lineNum) {
  if (a.globalData.consuc === true) {
    console.log("--已连接成功断开不做重试--");
    return;
  }
  if (getApp().globalData._that && getApp().globalData._that.data.openLockStat) {
    console.log("--开锁后不做重连");
    return;
  }
  _RetryCount++

  console.log("【自动尝试重连设备...】：" + _RetryCount + "--" + lineNum)

  newConnect(_DeviceName, _Callback, _ConnectTimeoutSize, true, null)
}


function scanBox() {
  console.log("scanBox---broadcastDevListCache--->", broadcastDevListCache);
  console.log("scanBox---broadcastDevList--->", broadcastDevList);
  //不进行蓝牙连接将蓝牙连接的变量置空
  console.log('broadcastDevList------------------------------------->', broadcastDevList)
  _DeviceName = null;
  _Device = null;
  _scanBoxFlg = true;
  //注释掉使用自己的缓存机制
  _allowDuplicatesKey = false;
  disconnect('BLE463');
  //先尝试关闭一次蓝牙适配器，再延迟500毫秒打开蓝牙适配器
  closeBluetoothAdapter(function () {

    setTimeout(function () {
      openBluetoothAdapter()
    }, _ServerConfigInfo.connectDelayed.openBluetoothAdapter)

  })
}

//断开蓝牙连接
function disconnect(lineNum, stopConnect) {
  if (getApp().globalData._that && getApp().globalData._that.data.openLockStat) {
    console.log("--开锁中不断开蓝牙");
    return;
  }
  if (a.globalData.isConnecting === true && stopConnect != 'stopConnect') {
    console.log("--连接中不断开蓝牙");
    return;
  } else if (stopConnect == 'stopConnect') {
    stopTimeout();
    stopOpenAdapterTimeout();
    stopLocationAuthTimeout();
    stopSendCommandTimeout();
  }
  console.warn("【UI层请求断开蓝牙连接】" + lineNum);
  if (getApp().globalData._that) {
    getApp().globalData.blepwd = null;
  }
  //关闭心跳定时器
  // if (getApp().globalData._that) {
  //   clearInterval(getApp().globalData._that.data.bleHeartTimer);
  // }

  _RetryCount = 0

  reset(function () {
    closeBluetoothAdapter(null)
    stopTimeout()
  })

}


//断开蓝牙连接
function thisDisconnect(info) {
  if (a.globalData.isConnecting === true) {
    console.log("--连接中不断开蓝牙--thisDisconnect");
    return;
  }
  console.warn("【BLELocker层请求断开连接】" + info);

  //关闭心跳定时器
  if (getApp().globalData._that) {
    clearInterval(getApp().globalData._that.data.bleHeartTimer);
  }

  _RetryCount = 0
  reset(function () {
    closeBluetoothAdapter(null)
    stopTimeout()
  })

}

//打开蓝牙适配器
function openBluetoothAdapter() {
  console.log("【正在打开蓝牙适配器】")

  if (wx.openBluetoothAdapter) {

    wx.openBluetoothAdapter({
      success: function (res) {
        statusChanged(Status.adaperOpenSuccess)

        console.log("【打开蓝牙适配器成功】", res)

        //检测手机蓝牙是否开启
        checkBLEStatus(function () {

          //监听蓝牙适配器状态变化
          onBluetoothAdapterStateChange()

          //开始扫描蓝牙设备
          setTimeout(function () {
            startBluetoothDevicesDiscovery()
          }, _ServerConfigInfo.connectDelayed.startBluetoothDevicesDiscovery)

        })

      },
      fail: function (res) {
        a.globalData.conErrDesc = 'OLD:openBluetoothAdapter fail:' + JSON.stringify(res);
        if (res.errCode == 10001 || res.errMsg.indexOf('not available') != -1) {
          showDialog("openBluetoothAdapter fail:" + JSON.stringify(res), Status.bleIsClosed, function () { });
        } else {
          showDialog("openBluetoothAdapter fail:" + JSON.stringify(res), Status.adaperOpenFail, function () { });
        }
        console.error("【error】【wx.openBluetoothAdapter】【打开蓝牙适配器失败】", res)
      }
    })


  } else {
    statusChanged(Status.appVersionNotSupported)

    console.error("【error】【appVersionNotSupported】【当前客户端版本不支持小程序蓝牙...(001)】")

  }
}

//检测手机蓝牙是否开启
function checkBLEStatus(callback) {

  console.log("【正在获取蓝牙适配器状态】")

  wx.getBluetoothAdapterState({
    success: function (res) {

      console.log("【获取蓝牙适配器状态成功】", res)

      if (res.available) {

        statusChanged(Status.bleIsOpened)

        console.log("【当前手机蓝牙已打开】")

        _IsBLEOpened = true

        if (res.discovering) {

          console.log("【当前正在扫描蓝牙设备】")

          console.log("【开始停止扫描蓝牙设备】")

          wx.stopBluetoothDevicesDiscovery({
            success: function (res) {
              statusChanged(Status.bleScanStop)

              console.log("【停止扫描蓝牙设备成功】", res)

              callback()
            },
            fail: function (res) {
              statusChanged(Status.bleScanStop)

              console.error("【error】【wx.stopBluetoothDevicesDiscovery】【停止扫描蓝牙设备失败】", res)

              callback()
            }
          })
        } else {

          callback()
        }

      } else {
        _IsBLEOpened = false
        statusChanged(Status.bleIsClosed)
        console.error("【error】【mobile not open ble】【手机蓝牙未打开】")
      }

    },
    fail: function (res) {
      console.error("【error】【wx.getBluetoothAdapterState】【获取蓝牙适配器状态失败】", res)
    }
  })
}

//关闭蓝牙适配器
function closeBluetoothAdapter(callback) {

  console.log("【请求关闭蓝牙适配器】")

  if (wx.closeBluetoothAdapter) {

    if (callback == null) {
      statusChanged(Status.adapterCloseing)
    }

    console.log("【正在关闭蓝牙适配器】")

    wx.closeBluetoothAdapter({
      success: function (res) {
        if (callback == null) {
          statusChanged(Status.adaperCloseSuccess)
          console.log("【关闭蓝牙适配器成功】", res)

        } else {
          console.log("【关闭蓝牙适配器成功】", res)
        }
        statusChanged(Status.normal)

        console.log("【设备已恢复到初始状态（001）】")

      },
      fail: function (res) {
        if (callback == null) {
          statusChanged(Status.adaperCloseFail)
          console.error("【error】【wx.closeBluetoothAdapter】【关闭蓝牙适配器失败】", res)


        } else {
          console.error("【error】【wx.closeBluetoothAdapter】【关闭蓝牙适配器失败】", res)

        }

        statusChanged(Status.normal)

        console.log("【设备已恢复到初始状态（002）】")

      },
      complete: function () {

        console.log("【关闭蓝牙适配器完成】")

        if (callback != null) {
          callback()
        }

      }
    })
  } else {
    statusChanged(Status.appVersionNotSupported)

    console.error("【error】【appVersionNotSupported】当前客户端版本不支持小程序蓝牙...(002)")

    // //蓝牙连接日志
    // var logData = {
    //   reqNumber: 5,
    //   optDesc: "当前客户端版本不支持小程序蓝牙...(002)"
    // };
    // recordConnectLog(logData)
  }

}

//监听蓝牙适配器状态变化
function onBluetoothAdapterStateChange() {

  console.log("【开始监听蓝牙适配器状态变化】")

  wx.onBluetoothAdapterStateChange(function (res) {
    console.log("【蓝牙适配器状态发生变化】", res)

    if (res.available == false) {
      if (_IsBLEOpened == true) {
        statusChanged(Status.bleClosed)
        console.log("【手动关闭蓝牙】")

      }
      _IsBLEOpened = false
    } else {
      if (_IsBLEOpened == false) {
        statusChanged(Status.bleOpened)
        console.log("【手动打开蓝牙】")
      }
      _IsBLEOpened = true
    }
  })

}

//开始扫描蓝牙设备
function startBluetoothDevicesDiscovery() {
  statusChanged(Status.bleScanStart)
  a.globalData.conErrDesc = 'OLD:开始扫描';
  console.log("【开始扫描蓝牙设备】")

  //监听扫描到蓝牙设备状态变化
  onBluetoothDeviceFound()

  // startLocationAuthTimeout()

  wx.startBluetoothDevicesDiscovery({
    allowDuplicatesKey: true,
    success: function (res) {
      statusChanged(Status.bleScaning)
      console.log("【正在扫描蓝牙设备中】", res)

      _IsScaning = true

    },
    fail: function (res) {
      a.globalData.conErrDesc = 'OLD:startBluetoothDevicesDiscovery fail:' + JSON.stringify(res);

      _IsScaning = false
      statusChanged(Status.bleScanFail)
      console.error("【error】【wx.startBluetoothDevicesDiscovery】【扫描蓝牙设备失败】", res)

      //尝试重新连接
      retryConnect('BLE816')
    }
  })

}

//监听扫描到蓝牙设备状态变化
function onBluetoothDeviceFound() {
  console.log("【开始监听扫描到蓝牙设备状态变化】")

  wx.onBluetoothDeviceFound(function (res) {
    handleFindDevices(res, true)
  })
}

// ArrayBuffer转16进度字符串示例
function ab2hex(buffer) {
  try {
    var hexArr = Array.prototype.map.call(
      new Uint8Array(buffer),
      function (bit) {
        return ('00' + bit.toString(16)).slice(-2)
      }
    )
  } catch (ex) {
    return null;
  }
  return hexArr.join('');
}

//处理找到的蓝牙设备
function handleFindDevices(res, showLog) {
  if (_IsScaning == false) {
    if (showLog) {
      console.log("【已经停止扫描，忽略扫描到的设备】", res.devices)
    }
    return
  }

  //解决报警群爆出的数组Invalid array length argument错误
  try {
    let a = res.devices.length;
  } catch (e) {
    console.log("数组长度无效", _DeviceName)
    return;
  }

  var isFind = false
  for (var i = 0; i < res.devices.length; i++) {
    var device = res.devices[i]
    let advertisData = ab2hex(device.advertisData);

    let devName = null;
    //避免同一个设备多次重复回调
    if (device.name == null) {
      console.log('【匹配设备失败，设备的name为空】');
    } else {
      devName = device.name;
    }
    if (device.localName == null) {
    } else {
      devName = device.localName;
    }
    if (devName && advertisData && devName.indexOf("DK") == 0) {
      let mac = devName.substring(2);
      let cacheStr = broadcastDevListCache[mac];
      if (cacheStr) {
        // console.log("mac=" + mac + "存在缓存");
        if (cacheStr == advertisData) {
          // console.log("mac="+mac+":广播没有变化！")
        } else {
          console.log("mac=" + mac + ":[广播发生变化]", cacheStr, advertisData)
          //接收到的广播数据
          broadcastDevListCache[mac] = advertisData;
          broadcastDevList[mac] = advertisData;
        }
      } else {
        console.log("mac=" + mac + ":不存在缓存")
        //接收到的广播数据
        broadcastDevListCache[mac] = advertisData;
        broadcastDevList[mac] = advertisData;
      }
    }


    if (_Device == null && _DeviceName != '' && _DeviceName != null && (device.name == _DeviceName || device.localName == _DeviceName)) {
      _Device = device
      isFind = true
      console.log("【搜索到蓝牙设备】搜索到设备", device, _DeviceName, advertisData)
      a.globalData.conErrDesc = 'OLD:搜索到设备';
      setTimeout(function () {
        console.log("broadcast-data---aaa->:", broadcastDevList)
        findDevStopDiscovery();
      }, 500);

      break
    }

  }

}

function findDevStopDiscovery(pt) {
  console.log("【已匹配到请求连接的设备】", pt)

  //监听蓝牙设备连接状态变化
  onBLEConnectionStateChange()

  console.log("【正在关闭蓝牙扫描】")
  _allowDuplicatesKey = true;//是否允许重复上报同一设备。如果允许重复上报，则 wx.onBlueToothDeviceFound 方法会多次上报同一设备，但是 RSSI 值会有不同。

  wx.stopBluetoothDevicesDiscovery({
    success: function (res) {
      statusChanged(Status.bleScanStop)
      console.log("【关闭蓝牙扫描成功】", res)
      _IsScaning = false
      //开始上传扫描到的设备信息
      // let rst = broadcastBack(pt);
      createBLEConnection('BLE989')
    },
    fail: function (res) {
      statusChanged(Status.bleScanStop)
      console.error("【error】【wx.stopBluetoothDevicesDiscovery】【关闭蓝牙扫描失败】", res)
      _IsScaning = false
      //连接已匹配的蓝牙设备
      createBLEConnection('BLE997')
    }
  })
  console.log("【正在关闭蓝牙扫描 end】")
}

//连接已匹配的蓝牙设备
function createBLEConnection(lineNum) {


  if (_Device == null || _Device == '') {
    console.log("不存在连接的设备...")
    stopTimeout();
    return;
  }

  console.log("【正在连接蓝牙设备中】" + _Device.name)

  a.globalData.isConnecting = true;
  a.globalData.conErrDesc = 'OLD:开始连接';
  wx.createBLEConnection({
    deviceId: _Device.deviceId,
    timeout: _CreateConnectionTimeoutSize,
    success: function (res) {
      // statusChanged(Status.bleConnectSuccess) 该状态没有使用
      console.log("【调用连接蓝牙设备函数完成】" + lineNum, res)
      a.globalData.isConnecting = false;
    },
    fail: function (res) {
      a.globalData.conErrDesc = 'OLD:连接失败:' + JSON.stringify(res);
      // statusChanged(Status.bleConnectFail) 该状态没有使用
      console.error("【error】【wx.createBLEConnection】【调用连接蓝牙设备函数失败】" + lineNum, res)
      a.globalData.isConnecting = false;
      if (res.errCode == -1 && res.errMsg == 'createBLEConnection:fail:already connect') {
        return
      }
      //尝试重新连接
      retryConnect('BLE1151')
    }
  })

}

//监听蓝牙设备连接状态变化
function onBLEConnectionStateChange() {
  console.log("【开始监听蓝牙设备连接状态变化】11")

  wx.onBLEConnectionStateChange(function (res) {
    if (_Device != null && res.deviceId == _Device.deviceId) {
      if (res.connected) {
        statusChanged(Status.bleReConnected)
        console.log("【蓝牙设备状态变化】【当前设备连接成功】", res)

        //延迟获取蓝牙设备的所有服务，查找满足要求的微信协议服务
        var delayTimeLen = _ServerConfigInfo.connectDelayed.getBLEDeviceServices
        if (_getBLEDeviceServiesRetryConCount == 1) {
          //第一次失败进行蓝牙重新连接后的延迟时间
          delayTimeLen = _getBLEDeviceServicesDelayTime
        }
        if (_getBLEDeviceServiesRetryConCount == 2) {
          //重连失败第二次重新连接,不进行函数调用直接使用uuid进行操作
          delayTimeLen = 500
        }
        setTimeout(function () {
          getBLEDeviceServices()
        }, delayTimeLen)

      } else {
        console.log("【蓝牙设备状态变化】【当前设备连接断开】", res)
        if (_IsFirstConnected == false) {
          //尝试重新连接
          retryConnect('BLE1193')
        } else {
          statusChanged(Status.bleDisconnected)

        }
      }
    } else {
      console.log("【蓝牙设备状态变化】【非当前设备】", res)
    }
  })

}

//获取蓝牙设备的所有服务，查找满足要求的微信协议服务
function getBLEDeviceServices() {
  console.log("【正在获取、查找蓝牙设备的微信服务】")

  wx.getBLEDeviceServices({
    deviceId: _Device ? _Device.deviceId : '',
    success: function (res) {
      //函数调用成功重试连接计数归零
      _getBLEDeviceServiesRetryConCount = 0

      console.log("【当前蓝牙设备的服务列表】", res)

      var isFind = false
      for (var i = 0; i < res.services.length; i++) {
        if (res.services[i].uuid.indexOf("0000FEE7") == 0) {
          _WXServiceUUID = res.services[i].uuid
          isFind = true
          break
        }
      }

      if (isFind == false) {
        statusChanged(Status.bleNotSupportWXService)

        console.error("【error】【bleNotSupportWXService】【未匹配微信蓝牙协议服务】")
        return
      }

      statusChanged(Status.bleSupportWXService)

      console.log("【已匹配微信蓝牙协议服务】")

      //延迟获取服务的所有特征
      setTimeout(function () {
        getBLEDeviceCharacteristics()
      }, _ServerConfigInfo.connectDelayed.getBLEDeviceCharacteristics)

    },
    fail: function (res) {

      console.error("【error】【wx.getBLEDeviceServices】【获取、查找蓝牙设备的微信服务失败】", res)

      //记录失败的日志到服务器
      if (_getBLEDeviceServiesRetryConCount == 0) {
        console.log("【正常获取失败,重连蓝牙,wx.getBLEDeviceServices函数调用失败】")
      } else if (_getBLEDeviceServiesRetryConCount == 1) {
        console.log("【第一次重连蓝牙失败,再重连】")
      } else if (_getBLEDeviceServiesRetryConCount == 2) {
        console.log("【第二次重连失败，再连】")
      } else {
        console.log("【获取服务失败,再次重连】")
      }

      _getBLEDeviceServiesRetryConCount += 1
      //重新连接蓝牙获取服务列表
      retryConnect('BLE1276')

    }

  })

}

//获取服务的所有特征
function getBLEDeviceCharacteristics() {
  console.log("【正在获取、查找蓝牙设备的微信特征】")

  let devId = _Device ? _Device.deviceId : '';

  wx.getBLEDeviceCharacteristics({
    deviceId: devId,
    serviceId: _WXServiceUUID,
    success: function (res) {

      console.log("【当前蓝牙设备的特征列表】", res)

      for (var i = 0; i < res.characteristics.length; i++) {
        if (res.characteristics[i].uuid.indexOf("FEC7") != -1) {
          _WXWriteUUID = res.characteristics[i].uuid
        } else if (res.characteristics[i].uuid.indexOf("FEC8") != -1) {
          _WXIndicateUUID = res.characteristics[i].uuid

          //启用特征值变化通知
          wx.notifyBLECharacteristicValueChange({
            state: true, // 启用 notify 功能
            deviceId: devId,
            serviceId: _WXServiceUUID,
            characteristicId: _WXIndicateUUID,
            success: function (res) { }
          })

        } else if (res.characteristics[i].uuid.indexOf("FEC9") != -1) {
          _WXReadUUID = res.characteristics[i].uuid
        }

      }

      if (_WXWriteUUID.length <= 0 || _WXIndicateUUID.length <= 0 || _WXReadUUID.length <= 0) {
        statusChanged(Status.bleNotSupportWXCharacteristic)
        console.error("【error】【bleNotSupportWXCharacteristic】【未匹配微信蓝牙协议特征】")
        return
      }

      _CollectionServiceInfo(_WXServiceUUID, _WXWriteUUID, _WXIndicateUUID, _WXReadUUID)

      console.log("【_WXWriteUUID】", _WXWriteUUID)
      console.log("【_WXReadUUID】", _WXReadUUID)
      console.log("【_WXIndicateUUID】", _WXIndicateUUID)

      statusChanged(Status.bleSupportWXCharacteristic)

      console.log("【已匹配微信蓝牙协议特征】")

      //监听微信蓝牙协议特征数据变化
      onBLECharacteristicValueChange()
    },
    fail: function (res) {
      console.bleError("【error】【wx.getBLEDeviceCharacteristics】【获取、查找蓝牙设备的微信特征失败】", res)
      console.log("【准备重新获取、查找蓝牙设备的微信特征】")
      //延迟获取服务的所有特征
      setTimeout(function () {
        getBLEDeviceCharacteristics()
      }, _ServerConfigInfo.connectDelayed.failGetBLEDeviceCharacteristics)

    }

  })

}

//监听微信蓝牙协议特征数据变化
function onBLECharacteristicValueChange() {
  statusChanged(Status.bleReceiveData)
  console.log("【开始监听微信蓝牙协议特征数据变化】")

  wx.onBLECharacteristicValueChange(function (characteristic) {
    const hex = buf2hex(characteristic.value).toUpperCase()
    console.log("【=====================接收到设备发来的数据】", hex)
    handleDeviceData(hex)
  })

}


//校验接受到的数据crc16码是否正确
function validateCrc16Code(hexData) {
  let data = hexData.substring(0, hexData.length - 4);
  let vCode = hexData.substring(hexData.length - 4);
  console.log("crc16-->", data, vCode);
  let validateCode = CRC16.ToModbusCRC16(data);
  EncryptUtil.pad(validateCode, 4);
  if (validateCode != vCode) {
    console.log("【蓝牙连接】数据CRC16校验失败，无法处理", validateCode);
    return false;
  }
  return true;
}

//处理解析设备发来的数据
function handleDeviceData(hex) {

  console.log("【开始处理收到的蓝牙设备数据】")

  if (_Status == Status.bleReceiveData || _Status == Status.ble01Data) { //接收数据状态，解析数据指令

    var length;
    var version;
    var seq;
    var command;
    if (hex.indexOf("E5") == 0) {
      let hexData = hex;
      let len = parseInt(hexData.substring(2, 4), 16) + 2;
      length = len.toString(16);      //长度
      version = hexData.substring(4, 6);       //版本
      seq = hexData.substring(6, 8);        //seq
      command = hexData.substring(8, 10);     //指令
    } else {
      version = hex.substring(2, 4) //版本号
      length = hex.substring(6, 8) //数据长度
      command = hex.substring(8, 12) //指令
      seq = hex.substring(12, 16) //seq
    }


   console.log("【version】" + version, parseInt(version, 16))
    console.log("【length】" + length, parseInt(length, 16))
    console.log("【command】" + command, parseInt(command, 16))
    console.log("【seq】" + seq, parseInt(seq, 16))


    if (command == '01') {

      console.info('【蓝牙连接】处理收到的随机数：', hex);
      let flg = validateCrc16Code(hex);
      if (!flg) {
        console.log("【蓝牙连接】随机数校验码失败");
        return;
      }
      _transferOpenLockCmd = true;
      _IsFirstConnected = true;
      //随机数
      _RandomNumKey = hex.substring(10, 18);
      console.info('【蓝牙连接】收到的随机数：', _RandomNumKey);
      getApp().globalData.randomNum = _RandomNumKey;
      getApp().globalData.blepwd = null;
      _Version = version;
      var softwareVersion = hex.substring(18, 28);
      _driverVersion = softwareVersion + '_' + hex.substring(28, 34);
      console.info('【蓝牙连接】硬件、软件版本号：' + _driverVersion);

      
      console.info('【蓝牙连接】软件版本：' + softwareVersion);
      getApp().globalData.softwareVersion = softwareVersion;

      let firmEquType = hex.substring(18, 20);
      console.info('【蓝牙连接】设备类型：' + firmEquType);
      getApp().globalData.firmEquType = firmEquType;

      statusChanged(Status.ble01Data)

    } else if (_RandomNumKey.length > 0) {
      statusChanged(Status.bleReceiveBaseData)
      console.log("【接收普通数据】正在接收普通数据...")

      _DataString = null
      _DataString = hex
      _DataSize = parseInt(length, 16)

      //检查是否已接收完普通数据
      checkReceiveData()

    } else if (parseInt(command, 16) == 10001) {
      statusChanged(Status.bleReceiveAuthData)
      console.log("【请求Auth指令】正在接收Auth数据...")


      _AuthString = null
      _AuthString = hex
      _AuthSize = parseInt(length, 16)

      //检查是否已接收完授权数据
      // checkReceiveAuth()

    } else if (parseInt(command, 16) == 10003) {
      statusChanged(Status.bleReceiveInitData)

      console.log("【请求Init指令】正在接收Init数据...")

      _InitString = null
      _InitString = hex
      _InitSize = parseInt(length, 16)

      //检查是否已接收完初始化数据
      // checkReceiveInit()

    } else if (parseInt(command, 16) == 10002) {
      statusChanged(Status.bleReceiveBaseData)

      console.log("【接收普通数据】正在接收普通数据...")

      _DataString = null
      _DataString = hex
      _DataSize = parseInt(length, 16)

      //检查是否已接收完普通数据
      checkReceiveData()

    }

  } else if (_Status == Status.bleReceiveAuthData) { //接收剩余授权数据
    _AuthString = _AuthString + hex

    //检查是否已接收完授权数据
    // checkReceiveAuth()
  } else if (_Status == Status.bleReceiveInitData) { //接收剩余初始化数据
    _InitString = _InitString + hex

    //检查是否已接收完初始化数据
    // checkReceiveInit()
  } else if (_Status == Status.bleReceiveBaseData) { //接收剩余普通数据
    _DataString = _DataString + hex

    //检查是否已接收完普通数据
    checkReceiveData()
  }

}



//检查是否已接收完普通数据
function checkReceiveData() {
  if (_DataString.length >= _DataSize * 2) {
    let isOld = isOldProcy();
    if (isOld) {
      return parseData(isOld);
    }

    //校验CRC16
    let flg = validateCrc16Code(_DataString);
    if (!isOld && !flg) {
      console.log("【蓝牙连接】数据CRC16校验失败，无法处理");
      return;
    }

    let app = getApp();
    let that = app.globalData._that;
    let macId = app.globalData.conMacId ? app.globalData.conMacId : that.data.macId;
    if (app.globalData.blepwd) {
      return parseData(isOld);
    } else {
      //重新获取秘钥
      wx.request({
        url: util.CONST_DATA.BASE_URL + 'ble/pwd',
        data:{
          mac: macId,
          random: app.globalData.randomNum
        },
        header: app.globalData.header,
        method: 'post',
        success:function(res){
          if(res.data.result==0){
            let pwd = res.data.data;
            app.globalData.blepwd = pwd;
            return parseData(isOld);
          }else {
            that.setData({
              loading_show:false
            })
            wx.showToast({
              title: '连接秘钥错误',
              icon:'none'
            })
          }
        },
        fail:function(){
          that.setData({
            loading_show: false
          })
          wx.showToast({
            title: '连接秘钥错误1',
            icon: 'none'
          })
        }
      })
    }
  }
}

function parseData(isOld) {
  let bussinessData = EncryptUtil.getBussinessData(_DataString, _DataSize, _transferOpenLockCmd, isOld)

  if (_BaseDataCallBack != null) {
    _BaseDataCallBack(bussinessData)
    statusChanged(Status.bleReceiveData)
    _BaseDataCallBack = null
    return
  }

  // _DataString = _DataString.substring(0, _DataSize * 2)




  // console.log("【接收普通数据】接收普通数据完成...")
  console.log("【接收普通数据】完整普通数据：", _DataString)
  console.log("【接收普通数据】解密后的数据：", bussinessData)

  if (bussinessData.cmdId == "88") { //85指令响应数据

    _Data88 = bussinessData.data


    console.log("【接收普通数据】88指令响应数据", _Data88)

    statusChanged(Status.ble88Data)

  } else if (bussinessData.cmdId == "85") { //85指令响应数据

    _Data85 = bussinessData.data


    console.log("【接收普通数据】85指令响应数据", _Data85)

    statusChanged(Status.ble85Data)

  } else if (bussinessData.cmdId == "95") { //95指令响应数据

    let app = getApp();
    
    _Data95 = bussinessData.data
    if (_driverVersion == null && _Data95.pile_ver) {
      //兼容新固件新驱动
      _driverVersion = _Data95.pile_ver;
    } else if (_driverVersion && !_Data95.pile_ver) {
      _Data95.pile_ver = _driverVersion;
    }

    console.log("【接收普通数据】95指令响应数据", _Data95, app.globalData.reStartCmd)

    if (_IsFirstConnected) {
      console.log("【连接共享轮椅---终点】", _reqId, _DeviceName);
    }

    statusChanged(Status.ble95Data)
    if(app.globalData.reStartCmd) {
      console.log("开始发送重启设备命令")
      sendRstartCommand();
      app.globalData.reStartCmd = false;
    }

  } else if (bussinessData.cmdId == "98") { //95指令响应数据

    _Data98 = bussinessData.data


    console.log("【接收普通数据】98指令响应数据", _Data98)

    statusChanged(Status.ble98Data)

  } else {


    console.log("【蓝牙连接】未处理的响应数据", bussinessData.data);
  }
  statusChanged(Status.bleReceiveData)
}

//校验授权数据，并发送授权请求响应数据包
function checkAuthAndSendAuthResponse(authRequest) {
  //校验授权数据正确性，这里目前未校验，默认认为是合法的设备
  // var hex = "FE01000E4E2100010A0208001200"

  let authResponseData = EncryptUtil.getAuthResponseData('', 0, '')


  console.log("【响应Auth指令】开始发送数据...", authResponseData)

  if (_Device != null) {
    writeData(authResponseData, function (isSuccess) {
      if (isSuccess) {

        console.log("【响应Auth指令】发送数据成功...")

      } else {

        console.error("【error】【send auth data fail】【响应Auth指令】发送数据失败...")

        //发送失败，重新校验授权数据，并发送授权请求响应数据包
        // checkAuthAndSendAuthResponse() 失败不进行重新验证,直接处理重新连接2018-04-15
        //重新连接蓝牙
        retryConnect('BLE1706')
      }
    }, 40)
  }

}

//校验初始化数据，并发送初始化请求响应数据包
function checkInitAndSendInitResponse(initRequest) {
  //校验初始化数据正确性，这里目前未校验，默认认为是合法的设备
  // var hex = "FE0100194E2300020A02080010B42418F8AC0120D1BBCABF07"

  let initResponseData = EncryptUtil.getInitResponseData(_EncryptValue, _TimeBytes, initRequest, 4660, 22136, 0, '')

  console.log("【响应Init指令】开始发送数据...", initResponseData)

  if (_Device != null) {
    writeData(initResponseData, function (isSuccess) {
      if (isSuccess) {

        console.log("【响应Init指令】发送数据成功...")

        statusChanged(Status.bleInitSuccess)
        statusChanged(Status.bleReceiveData)
        console.log("【===设备授权初始化完成===】")

        _IsFirstConnected = true

        //发送95指令给设备
        send95Command(null)

      } else {
        console.error("【error】【send init data fail】【响应Init指令】发送数据失败...")

        //发送失败，重新校验初始化数据，并发送初始化请求响应数据包
        checkInitAndSendInitResponse(initRequest)
      }
    }, 40)
  }

}

//发送控制盒广播配置信息
function sendBroadcastConfCommand() {
  var _that = getApp().globalData._that;
  var params = _that && _that.data.conDevExtParams ? _that.data.conDevExtParams.broadcast88conf : "";
  if (params) {
    var hexStr = 'FE01001400510000' + params + "00";
    var crc16 = CRC16.ToModbusCRC16(hexStr);;
    var hex = hexStr + crc16;
    console.log("---sendBroadcastConCommand-->", hex);
    writeData(hex, function (isSuccess) {
      console.log("---sendBroadcastConCommand--isSuc=", isSuccess);
    });
  }


}

//发送85指令给设备
function send85Command(callback) {
  _BaseDataCallBack = null
  console.log('send85Command', _Status)
  stopSendCommandTimeout();
  start85Back1Timeout(Status.ble85Back1Timeout);
  if (_Status != Status.bleReceiveData && callback != null) {
    callback(false)
    return
  }

  _Data85 = null //解析后的85数据
  // var hex = 'FE010010753100000A00120238351800'

  let sendHexStr;

  if (_transferOpenLockCmd) {

    sendHexStr = EncryptUtil.getSendDataRequestHexStr('88', isOldProcy(), _Version);

    console.log('【蓝牙连接】准备发送88指令数据：' + sendHexStr);
    console.log("【发送88指令】开始发送数据...", sendHexStr)

  } else {
    sendHexStr = EncryptUtil.getSendDataRequestHexStr('85', isOldProcy(), _Version);

    console.log('【蓝牙连接】准备发送85指令数据：' + sendHexStr);
    console.log("【发送85指令】开始发送数据...", sendHexStr)
  }

  if (_Device != null) {
    writeData(sendHexStr, function (isSuccess) {
      if (isSuccess) {
        if (_Data95 && _Data95.pile_ver && _Data95.pile_ver.slice(-6) >= '191101') {//新新驱动
          start85Back2Timeout(Status.ble85Back2Timeout);
        }
        if (_transferOpenLockCmd) {
          console.log("【发送88指令】发送数据成功...")
        } else {
          console.log("【发送85指令】发送数据成功...")
        }

        if (callback != null) {
          callback(true)
        }
      } else {
        if (_transferOpenLockCmd) {
          console.error("【error】【send 88 data fail】【发送88指令】发送数据失败...")
        } else {
          console.error("【error】【send 85 data fail】【发送85指令】发送数据失败...")
        }
        if (callback == null) {
          //发送失败，重新发送85指令
          send85Command(callback)
        } else {
          callback(false)
        }
      }
    }, 40)
  }
}

//发送重启指令给设备
function sendRstartCommand(callback) {
  _BaseDataCallBack = null
  console.log('sendRestartCommand', _Status)
  if (_Status != Status.bleReceiveData && callback != null) {
    callback(false)
    return
  }

  // var hex = 'FE010010753100000A00120238351800'

  let sendHexStr = EncryptUtil.getSendDataRequestHexStr('12', false,  _Version);

  console.log('【蓝牙连接】准备发送12指令数据：' + sendHexStr);
  console.log("【发送12指令】开始发送数据...", sendHexStr)

  if (_Device != null) {
    writeData(sendHexStr, function (isSuccess) {
      if (isSuccess) {
        wx.showToast({
          title: '发送成功',
        })
        if (callback != null) {
          callback(true)
        }
      } else {
        wx.showToast({
          title: '发送失败',
        })
        if (callback != null) {
          callback(false)
        }
      }
    }, 40)
  }
}


//心跳包
function send90Command(step) {
  if (!step) {
    step = '0';
  } else if (parseInt(step, 16) < 11) {
    step = '0' + step;
  }
  let sendHexStr = EncryptUtil.getSendDataRequestHexStr('90' + step, isOldProcy())
  console.log("【发送90指令】开始发送数据...", sendHexStr)
  if (_Device != null) {
    writeData(sendHexStr, function (isSuccess) {
      if (isSuccess) {
        console.log("【发送90指令】发送数据成功...")
      } else {
        console.error("【error】【send 90 data fail】【发送90指令】发送数据失败...")
      }
    }, 40)
  }
}

//发送95指令给设备
function send95Command(callback) {
  _BaseDataCallBack = null

  stopSendCommandTimeout()
  if (_Status != Status.bleReceiveData && callback != null) {
    callback(false)
    return
  }

  if (callback != null) {
    startSendCommandTimeout(Status.bleSend95Timeout)
  }

  _Data95 = null //解析后的95数据
  // var hex = 'FE010010753100000A00120239351800'
  let sendHexStr = EncryptUtil.getSendDataRequestHexStr('95', isOldProcy(), _Version)


  console.log("【发送95指令】开始发送数据...", sendHexStr)

  if (_Device != null) {
    writeData(sendHexStr, function (isSuccess) {
      if (isSuccess) {

        console.log("【发送95指令】发送数据成功...")

        if (callback != null) {
          callback(true)
        }

      } else {

        console.error("【error】【send 95 data fail】【发送95指令】发送数据失败...")

        if (callback == null) {
          //发送失败，重新发送95指令
          send95Command(callback)
        } else {
          callback(false)
        }

      }
    }, 40)
  }

}

//发送95指令给设备
function send98Command(callback) {
  _BaseDataCallBack = null

  stopSendCommandTimeout()
  if (_Status != Status.bleReceiveData && callback != null) {
    callback(false)
    return
  }

  _Data98 = null //解析后的95数据
  // var hex = 'FE010010753100000A00120239351800'
  let sendHexStr = EncryptUtil.getSendDataRequestHexStr('98', isOldProcy(), _Version)

  console.log("【发送98指令】开始发送数据...", sendHexStr)

  if (_Device != null) {
    writeData(sendHexStr, function (isSuccess) {
      if (isSuccess) {
        console.log("【发送98指令】发送数据成功...")

        if (callback != null) {
          callback(true)
        }

      } else {
        console.error("【error】【send 98 data fail】【发送98指令】发送数据失败...")

        if (callback == null) {
          //发送失败，重新发送95指令
          send98Command(callback)
        } else {
          callback(false)
        }

      }
    }, 40)
  }

}

//发送B0指令给设备
function sendB0Command(callback) {
  _BaseDataCallBack = null

  stopSendCommandTimeout()
  if (_Status != Status.bleReceiveData && callback != null) {
    callback(false)
    return
  }

  if (callback != null) {
    startSendCommandTimeout(Status.bleSendB0Timeout)
  }

  let sendHexStr = EncryptUtil.getSendDataRequestHexStr('B0', isOldProcy())
  console.log('【蓝牙连接】准备发送B0指令数据：' + sendHexStr);
  console.log("【发送B0指令】开始发送数据...", sendHexStr)

  if (_Device != null) {
    writeData(sendHexStr, function (isSuccess) {
      stopSendCommandTimeout()
      if (isSuccess) {
        console.log("【发送B0指令】发送数据成功...")

        if (callback != null) {
          callback(true)
        }
      } else {
        console.error("【error】【send B0 data fail】【发送B0指令】发送数据失败...")
        if (callback == null) {
          //发送失败，重新发送B0指令
          sendB0Command(callback)
        } else {
          callback(false)
        }
      }
    }, 40)
  }
}

//发送BASE指令
function sendBaseCommand(command, callback, dataCallback) {
  _BaseDataCallBack = null

  stopSendCommandTimeout()
  if (_Status != Status.bleReceiveData && callback != null) {
    callback(false)
    return
  }

  _BaseDataCallBack = dataCallback

  if (callback != null) {
    startSendCommandTimeout(Status.bleSendBaseTimeout)
  }

  console.log('【蓝牙连接】准备发送BASE指令：' + command);
  let sendHexStr = EncryptUtil.getSendDataRequestHexStr(command, isOldProcy())
  console.log('【蓝牙连接】准备发送BASE指令数据：' + sendHexStr);
  console.log("【发送BASE指令】开始发送数据...", sendHexStr)

  if (_Device != null) {
    writeData(sendHexStr, function (isSuccess) {
      stopSendCommandTimeout()
      if (isSuccess) {
        console.log("【发送BASE指令】发送数据成功...")

        if (callback != null) {
          callback(true)
        }
      } else {
        console.error("【error】【send BASE data fail】【发送BASE指令】发送数据失败...")
        if (callback == null) {
          //发送失败，重新发送BASE指令
          sendBaseCommand(command, callback, dataCallback)
        } else {
          callback(false)
        }
      }
    }, 40)
  }
}

//发送数据给设备
function writeData(hex, callback, cmdSize) {
  //每次发送都延迟一下
  setTimeout(function () {

    if (_Device == null) {
      return
    }

    var sendHex = hex
    var lastHex = null

    //发送的数据长度大于40，拆分后发送
    if (hex.length > cmdSize) {
      sendHex = hex.substring(0, cmdSize)
      lastHex = hex.substring(cmdSize, hex.length)
    } else {
      lastHex = null
    }

    var typedArray = new Uint8Array(sendHex.match(/[\da-f]{2}/gi).map(function (h) {
      return parseInt(h, 16)
    }))
    var buffer = typedArray.buffer
    console.log("【正在发送数据】", sendHex, typedArray, _Device, _WXServiceUUID, _WXWriteUUID)

    wx.writeBLECharacteristicValue({
      deviceId: _Device.deviceId,
      serviceId: _WXServiceUUID,
      characteristicId: _WXWriteUUID,
      value: buffer,
      success: function (res) {
        console.log("【wx.writeBLECharacteristicValue】【发送数据成功】")

        if (lastHex == null) {
          callback(true)
        } else {
          writeData(lastHex, callback, cmdSize)
        }
      },
      fail: function (res) {
        console.error("【error】【wx.writeBLECharacteristicValue】【发送数据失败】", res)
        callback(false);
      }
    })

  }, _ServerConfigInfo.connectDelayed.writeData)
}

//将设备发的数据转换为16进制
function buf2hex(buffer) {
  return Array.prototype.map.call(new Uint8Array(buffer), x => ('00' + x.toString(16)).slice(-2)).join('')
}

/**
 * 将Base64字符串转换成Byte数组
 * @return [0x00,0x00]
 * @param 字符串
 */
function base64_to_bytes_array(base64String) {
  var result = new Array();
  if (base64String.length % 4 != 0 || base64String.length == 0) {
    return result;
  }
  var b64Chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';
  // 先将后面的字段转换成原来的Byte数组
  var len = base64String.length;
  var endBytes = new Array();
  if (base64String.charAt(len - 1) == "=") {
    if (base64String.charAt(len - 2) == "=") { // 有两个等号的情况
      var s1 = base64String.charAt(len - 4); // 后面的第一个字符
      var s2 = base64String.charAt(len - 3); // 后面的第二个字符
      var v1 = ((b64Chars.indexOf(s1) << 2) & 0xFF) + (b64Chars.indexOf(s2) >> 4); //这个就是最后面的一个字节

      endBytes[0] = v1;
    } else { // 只有一个等号的情况
      var s1 = base64String.charAt(len - 4); // 后面的第一个字符
      var s2 = base64String.charAt(len - 3); // 后面的第二个字符
      var s3 = base64String.charAt(len - 2); // 后面的第三个字符

      var v1 = ((b64Chars.indexOf(s1) << 2) & 0xFF) + (b64Chars.indexOf(s2) >> 4); //这个就是最后面的第一个字节
      var v2 = ((b64Chars.indexOf(s2) << 4) & 0xFF) + (b64Chars.indexOf(s3) >> 2); //这个就是最后面的第二个字节

      endBytes[0] = v1;
      endBytes[1] = v2;
    }
  }

  var times = base64String.length / 4;

  for (var i = 0; i < times - (endBytes.length == 0 ? 0 : 1); i++) {
    var startIndex = i * 4;
    var V1 = base64String.charAt(startIndex + 0);
    var V2 = base64String.charAt(startIndex + 1);
    var V3 = base64String.charAt(startIndex + 2);
    var V4 = base64String.charAt(startIndex + 3);

    result[i * 3 + 0] = ((b64Chars.indexOf(V1) << 2) & 0xFF) + (b64Chars.indexOf(V2) >> 4);
    result[i * 3 + 1] = ((b64Chars.indexOf(V2) << 4) & 0xFF) + (b64Chars.indexOf(V3) >> 2);
    result[i * 3 + 2] = ((b64Chars.indexOf(V3) << 6) & 0xFF) + b64Chars.indexOf(V4);
  }
  return result.concat(endBytes);
}

/**
 * 把字节数组按16进制打印,这里需要保证数组的每个元素是Number类型
 * @param bytes
 */
function getHexBody(bytes) {
  var hexString = "Head:[";
  var len = 0;
  for (var i = 0; i < bytes.length; i++) {
    for (var i = 0; i < bytes.length; i++) {
      if (i === bytes.length - 1 || i === 23) hexString += (bytes[i] > 0xF ? bytes[i].toString(16) : "0" + bytes[i].toString(16));
      else hexString += (bytes[i] > 0xF ? bytes[i].toString(16) : "0" + bytes[i].toString(16)) + ",";
      if (i === 23) {
        hexString += "]<br/>Body:[";
        len = hexString.length;
      }
    }
  }
  console.log("hexbody-----" + hexString)
  hexString = hexString.substr(len);
  var hexArr = hexString.split(",");
  var result = "";
  for (var i = 0; i < hexArr.length; i++) {
    var tmp = '0x' + hexArr[i];
    result += String.fromCharCode(tmp);
  }
  return result;
}

//强制设置中转85指令为88
function transfer85To88() {

  //是否中转85开锁指令为88开锁指令
  _transferOpenLockCmd = true

  console.log("【85指令中转88指令】UI层强制中转85指令为88指令...")

}

function getDriverVersion() {
  return _driverVersion
}

//是否是就固件驱动 true是,false不是
function isOldProcy() {
  return _RandomNumKey.length == 0;
}

function setParams(callback, that) {
  _Callback = callback;
  _that = that;
}
function setDevice(device) {
  _Device = device;
}
function setWriteUuid(wuuid, wxsuuid) {
  _WXWriteUUID = wuuid;
  _WXServiceUUID = wxsuuid;
}

function recordBroadcastMac(devName, advertisData) {
  if (devName && advertisData) {
    let mac = devName.substring(2);
    let cacheStr = broadcastDevListCache[mac];
    if (cacheStr) {
      // console.log("mac=" + mac + "存在缓存");
      if (cacheStr == advertisData) {
        // console.log("mac="+mac+":广播没有变化！")
      } else {
        //接收到的广播数据
        broadcastDevListCache[mac] = advertisData;
        broadcastDevList[mac] = advertisData;
      }
    } else {
      console.log("mac=" + mac + ":不存在缓存")
      //接收到的广播数据
      broadcastDevListCache[mac] = advertisData;
      broadcastDevList[mac] = advertisData;
    }
  }
}

function isValidBTDeviceName(e) {
  return new RegExp("^DK.*$", "i").test(e);
}


function showDialog(i, status, t) {
  console.log("连接超时:", i)
  a.globalData.conErrDesc = i;
  stopTimeout();
  _that = _that ? _that : getApp().globalData._that;
  obBleUninstall(_that);
  if (arguments.length == 3) {
    statusChanged(status);
  } else {
    statusChanged(Status.bleConnectTimeout);
  }
}

function newConnect(deviceName, statusCallback, timeout, isRetry, encryptValue, timeBytes, that) {
  console.log("----start connect-------<>----####", deviceName)
  _that = that;
  obBleUninstall(that);
  that.data.curDevName = deviceName;
  getApp().globalData._that = that;
  setParams(statusCallback, that);
  openAdapterCount = 3;
  s = 3;
  obBleInstall(that);
}


function obBleInstall(that) {
  a.globalData.conErrDesc = '';
  console.log("--------->bleinstall>>>>>>>>>>>>>>>>>>");
  var e = that, curDevName = e.data.curDevName;
  startTimeout();
  startOpenAdapterTimeout();
  startLocationAuthTimeout();
  wx.openBluetoothAdapter({
    success: function (t) {
      stopOpenAdapterTimeout();
      wx.getBluetoothDevices({
        success: function (t) {
          console.log('getBluetoothDevices', t);
          for (var n = 0; ; n++) {
            if (n >= t.devices.length) {
              console.log("uniqueId:[" + curDevName + "] not cached"),
                wx.startBluetoothDevicesDiscovery({
                  allowDuplicatesKey: !0,
                  success: function (e) {
                    console.log(e);
                  },
                  fail: function (e) {
                    console.log(e);
                    if (e.errCode === 10000 && openAdapterCount > 0) {
                      //蓝牙适配器未初始化，重新初始化处理
                      setTimeout(() => {
                        console.warn("getBLEDeviceServices not init retry:", openAdapterCount);
                        obBleInstall(that);
                        openAdapterCount--;
                      }, openAdapterTime * (3 - openAdapterCount));
                    } else {
                      stopLocationAuthTimeout();
                      showDialog("startBluetoothDevicesDiscovery fail:" + JSON.stringify(e), function () { });
                    }
                  }
                });
              break;
            }
            var deviceId = t.devices[n].deviceId;

            let devName = null;
            if (t.devices[n].localName == null) {
              console.log('【匹配设备失败，设备的localName为空】');
            } else {
              devName = t.devices[n].localName;
            }
            if (t.devices[n].name == null && devName == null) {
              console.log('【匹配设备失败，设备的name为空】');
            } else {
              devName = t.devices[n].name;
            }

            if (devName && devName == e.data.curDevName) {
              e.setData({
                deviceId: deviceId
              });


              setDevice(t.devices[n]);

              console.log("uniqueId:[" + curDevName + "] cached");
              doConnection(that);
              break;
            } else;
          }
        },
        fail: function (res) {
          console.log("getBluetoothDevices fail:", res);
          if (res.errCode === 10000 && openAdapterCount > 0) {
            //蓝牙适配器未初始化，重新初始化处理
            setTimeout(() => {
              console.warn("adapter not init retry ", openAdapterCount)
              obBleInstall(that);
              openAdapterCount--;
            }, openAdapterTime * (3 - openAdapterCount));
          } else {
            //蓝牙未打开请先打开蓝牙
            stopLocationAuthTimeout();
            showDialog("getBluetoothDevices fail:" + JSON.stringify(res), Status.bleConnectTimeout, function () { });
          }
        }
      });
    },
    fail: function (i) {
      console.log('openBluetoothAdapter', i);
      stopOpenAdapterTimeout();
      wx.hideLoading();
      if (i.errCode === 10000 && openAdapterCount > 0) {
        //蓝牙适配器未初始化，重新初始化处理
        setTimeout(() => {
          console.warn("adapter fail not init retry ", openAdapterCount)
          obBleInstall(that);
          openAdapterCount--;
        }, openAdapterTime * (3 - openAdapterCount));
      } else {
        //蓝牙未打开请先打开蓝牙
        stopLocationAuthTimeout();
        if (i.errCode == 10001 || i.errMsg.indexOf('not available') != -1) {
          showDialog("openBluetoothAdapter fail:" + JSON.stringify(i), Status.bleIsClosed, function () { });
        } else {
          showDialog("openBluetoothAdapter fail:" + JSON.stringify(i), Status.adaperOpenFail, function () { });
        }
      }
    }
  });

  var flg = true;
  var startFoundTime = new Date().getTime();
  var foundTimeoutFlg = false;
  wx.onBluetoothDeviceFound(function (n) {
    stopLocationAuthTimeout();
    if (flg)
      for (var a = 0; a < n.devices.length; a++) {

        let devName = null;
        let advertisData = ab2hex(n.devices[a].advertisData);
        if (advertisData) {
          let head = advertisData.substring(0, 4);
          if (head > 5701) {
            let adMacName = advertisData.substring(4, 12);
            let dname = 'DK' + adMacName.toUpperCase();
            if (curDevName === dname) {
              devName = dname;
              console.log("--->adMac=", devName);
            }
          }
        }
        if (devName == null) {
          if (n.devices[a].localName == null) {
            console.log('【匹配设备失败，设备的localName为空】');
          } else {
            devName = n.devices[a].localName;
          }
          if (n.devices[a].name == null && devName == null) {
            console.log('【匹配设备失败，设备的name为空】');
          } else {
            devName = n.devices[a].name;
          }
        }

        if (isValidBTDeviceName(devName)) {
          recordBroadcastMac(devName, advertisData);
        }

        if (isValidBTDeviceName(devName) && curDevName === devName) {
          setDevice(n.devices[a]);
          var d = n.devices[a].deviceId;
          if (flg) {
            flg = false;
            e.setData({
              deviceId: d
            });
            console.log("get it:[" + d + "][" + curDevName + "]" + "[" + advertisData + "]");
            doConnection(that);
          };
          break;
        } else if (flg === !0) {
          let curTime = new Date().getTime();
          let diff = curTime - startFoundTime;
          let searchTimeout = 15000;
          if (that.data.curIsDirectCon) {
            searchTimeout = 10000;
          }
          if (diff > searchTimeout && !foundTimeoutFlg) {
            foundTimeoutFlg = true;
            flg = false;
            //超出搜索时长未搜索到设备
            wx.stopBluetoothDevicesDiscovery({
              success: function (res) {
                console.log("aaa stop discover suc", res);
              }, fail: function (err) {
                console.log("aaa----stop Fail---111", err)
              }, complete: function (res) {
                console.log("aaa----complate stop discovery--->", res)
                showDialog("搜索超时", function () { });
              }
            });
            break;
          }
        }
      }
  });
}

function doConnection(that) {
  console.log(">>>>搜索到设备停止搜索>>>>")
  var e = that;
  wx.stopBluetoothDevicesDiscovery({
    complete: function (i) {
      console.log(i);
      if (i.errCode === 10000 && openAdapterCount > 0) {
        //蓝牙适配器未初始化，重新初始化处理
        setTimeout(() => {
          console.warn("stopdiscover not init retry:", openAdapterCount);
          obBleInstall(that);
          openAdapterCount--;
        }, openAdapterTime * (3 - openAdapterCount));
      } else {
        connection(that);
      }
    }
  });
}


function connection(that) {

  a.globalData.consuc = false;
  console.log(">>>>开始连接>>>>")
  stopLocationAuthTimeout();
  stopOpenAdapterTimeout();
  var e = that;
  _that = that;
  setTimeout(function () {
    a.globalData.isConnecting = true;
    wx.createBLEConnection({
      deviceId: e.data.deviceId,
      timeout: _CreateConnectionTimeoutSize,
      success: function (i) {
        a.globalData.isConnecting = false;
        wx.onBLEConnectionStateChange(function (e) {
          console.log("res.deviceId:[" + e.deviceId + "][" + e.connected + "]");
        }), setTimeout(function () {
          wx.getBLEDeviceServices({
            deviceId: e.data.deviceId,
            success: function (i) {
              e.setData({
                services: i.services
              });
              for (var t = 0; t < i.services.length; t++) if (-1 != i.services[t].uuid.toUpperCase().indexOf("0000FEE7")) {
                console.log("------getFEE7----->");
                e.setData({
                  serviceId: e.data.services[t].uuid
                });
                break;
              }
              console.log("------START--getBLEDeviceCharacteristics----->");

              setTimeout(function () {
                wx.getBLEDeviceCharacteristics({
                  deviceId: e.data.deviceId,
                  serviceId: e.data.serviceId,
                  success: function (i) {
                    console.log("device getBLEDeviceCharacteristics:", i.characteristics);
                    let count = 0;
                    for (var t = 0; t < i.characteristics.length; t++) {
                      if (-1 != i.characteristics[t].uuid.toUpperCase().indexOf("FEC8")) {
                        e.setData({
                          char6UUID: i.characteristics[t].uuid
                        });
                        count++;
                      } else if (-1 != i.characteristics[t].uuid.toUpperCase().indexOf("FEC7")) {
                        setWriteUuid(i.characteristics[t].uuid, e.data.serviceId);
                        count++;
                      }
                      if (count == 2) {
                        break;
                      }
                    }
                    wx.notifyBLECharacteristicValueChanged({
                      deviceId: e.data.deviceId,
                      serviceId: e.data.serviceId,
                      characteristicId: e.data.char6UUID,
                      state: !0,
                      success: function (i) {
                        e.setData({
                          status: !0
                        });
                      },
                      fail: function (i) {
                        console.log("notifyBLECharacteristicValueChanged fail", i);
                        10005 === i.errCode && s >= 0 ? (wx.hideLoading(),
                          obBleInstall(that)) : (e.setData({
                            status: !1
                          }), wx.hideLoading(), showDialog("notifyBLECharacteristicValueChanged fail." + JSON.stringify(i), function () { }));
                      }
                    }),
                      //监听状态值变化
                      onBLECharacteristicValueChange();
                    a.globalData.connect_stat = 'success';
                  },
                  fail: function (i) {
                    if (i.errCode === 10005 && openAdapterCount > 0) {
                      wx.hideLoading();
                      wx.closeBLEConnection({
                        deviceId: that.data.deviceId,
                        complete: function () {
                          obBleInstall(that);
                        }
                      });
                    } else {
                      console.log(i), showDialog("getBLEDeviceCharacteristics fail." + JSON.stringify(i), Status.bleConnectTimeout, function () { });
                    }
                  }
                });
              }, 10);
            },
            fail: function (i) {
              if (i.errCode === 10000 && openAdapterCount > 0) {
                //蓝牙适配器未初始化，重新初始化处理
                setTimeout(() => {
                  console.warn("getBLEDeviceServices not init retry:", openAdapterCount);
                  obBleInstall(that);
                  openAdapterCount--;
                }, openAdapterTime * (3 - openAdapterCount));
              } else if (i.errCode === 10004 && openAdapterCount > 0) {
                //关闭连接重新连接尝试
                wx.hideLoading();
                wx.closeBLEConnection({
                  deviceId: that.data.deviceId,
                  complete: function () {
                    obBleInstall(that);
                  }
                });
              } else {
                console.log(i), showDialog("getBLEDeviceServices fail." + JSON.stringify(i), function () { });
              }
            }
          });
        }, 50);
      },
      fail: function (i) {
        if (i.errCode === -1 && i.errMsg.indexOf("already connect") != -1) {
          //已经连接,重新开关蓝牙重试
          a.globalData.isConnecting = false;

          wx.onBLEConnectionStateChange(function (e) {
            console.log("res.deviceId:[" + e.deviceId + "][" + e.connected + "]");
          }), setTimeout(function () {
            wx.getBLEDeviceServices({
              deviceId: e.data.deviceId,
              success: function (i) {
                e.setData({
                  services: i.services
                });
                for (var t = 0; t < i.services.length; t++) if (-1 != i.services[t].uuid.toUpperCase().indexOf("0000FEE7")) {
                  console.log("------getFEE7----->");
                  e.setData({
                    serviceId: e.data.services[t].uuid
                  });
                  break;
                }
                console.log("------START--getBLEDeviceCharacteristics----->");

                setTimeout(function () {
                  wx.getBLEDeviceCharacteristics({
                    deviceId: e.data.deviceId,
                    serviceId: e.data.serviceId,
                    success: function (i) {
                      console.log("device getBLEDeviceCharacteristics:", i.characteristics);
                      let count = 0;
                      for (var t = 0; t < i.characteristics.length; t++) {
                        if (-1 != i.characteristics[t].uuid.toUpperCase().indexOf("FEC8")) {
                          e.setData({
                            char6UUID: i.characteristics[t].uuid
                          });
                          count++;
                        } else if (-1 != i.characteristics[t].uuid.toUpperCase().indexOf("FEC7")) {
                          setWriteUuid(i.characteristics[t].uuid, e.data.serviceId);
                          count++;
                        }
                        if (count == 2) {
                          break;
                        }
                      }
                      wx.notifyBLECharacteristicValueChanged({
                        deviceId: e.data.deviceId,
                        serviceId: e.data.serviceId,
                        characteristicId: e.data.char6UUID,
                        state: !0,
                        success: function (i) {
                          e.setData({
                            status: !0
                          });
                        },
                        fail: function (i) {
                          console.log("notifyBLECharacteristicValueChanged fail", i);
                          10005 === i.errCode && s >= 0 ? (wx.hideLoading(),
                            obBleInstall(that)) : (e.setData({
                              status: !1
                            }), wx.hideLoading(), showDialog("notifyBLECharacteristicValueChanged fail." + JSON.stringify(i), function () { }));
                        }
                      }),
                        //监听状态值变化
                        onBLECharacteristicValueChange();
                      a.globalData.connect_stat = 'success';
                    },
                    fail: function (i) {
                      if (i.errCode === 10005 && openAdapterCount > 0) {
                        wx.hideLoading();
                        wx.closeBLEConnection({
                          deviceId: that.data.deviceId,
                          complete: function () {
                            obBleInstall(that);
                          }
                        });
                      } else {
                        console.log(i), showDialog("getBLEDeviceCharacteristics fail." + JSON.stringify(i), Status.bleConnectTimeout, function () { });
                      }
                    }
                  });
                }, 10);
              },
              fail: function (i) {
                if (i.errCode === 10000 && openAdapterCount > 0) {
                  //蓝牙适配器未初始化，重新初始化处理
                  setTimeout(() => {
                    console.warn("getBLEDeviceServices not init retry:", openAdapterCount);
                    obBleInstall(that);
                    openAdapterCount--;
                  }, openAdapterTime * (3 - openAdapterCount));
                } else if (i.errCode === 10004 && openAdapterCount > 0) {
                  //关闭连接重新连接尝试
                  wx.hideLoading();
                  wx.closeBLEConnection({
                    deviceId: that.data.deviceId,
                    complete: function () {
                      obBleInstall(that);
                    }
                  });
                } else {
                  console.log(i), showDialog("getBLEDeviceServices fail." + JSON.stringify(i), function () { });
                }
              }
            });
          }, 50);
        } else if (i.errCode === 10000 && openAdapterCount > 0) {
          //蓝牙适配器未初始化，重新初始化处理
          setTimeout(() => {
            console.warn("getBLEDeviceServices not init retry:", openAdapterCount);
            obBleInstall(that);
            openAdapterCount--;
          }, openAdapterTime * (3 - openAdapterCount));
        } else {
          a.globalData.isConnecting = false;
          console.log(i);
          s -= 1;
          c += 500;
          if ((10006 === i.errCode || 10012 === i.errCode) && s >= 0) {
            setTimeout(function () {
              connection(that);
            }, c)
          } else if (10003 === i.errCode && s >= 0) {
            wx.hideLoading();
            obBleInstall(that);
          } else if (10008 === i.errCode && s >= 0) {
            //系统错误重试连接
            wx.hideLoading();
            wx.closeBLEConnection({
              deviceId: that.data.deviceId,
              complete: function () {
                obBleInstall(that);
              }
            });
          } else {
            wx.hideLoading();
            showDialog("createBLEConnection fail:" + JSON.stringify(i), Status.bleConnectTimeout, function () { });
          }
        }
      }
    });
  }, 50);
}

function obBleUninstall(that) {
  console.log("*****uncon 1111*****");

  var e = that;
  wx.stopBluetoothDevicesDiscovery({
    success: function (res) {
      console.log("stop discover suc", res);
    }, fail: function (err) {
      console.log("----stop Fail---111", err)
    },
    complete: function (res) {
      console.log("----complate stop discovery--->", res)
    }
  });
  if (e && e.data && e.data.deviceId) {
    wx.closeBLEConnection({
      deviceId: e.data.deviceId,
      complete: function () {
        wx.closeBluetoothAdapter()
      }
    })
  }
}


/**
 * 安卓直连start
 */
function directConnect(deviceName, statusCallback, timeout, isRetry, encryptValue, timeBytes, that) {
  _that = that;
  that.data.stopConnect = false;
  that.setData({
    loading_show: true,
    loading_desc: '设备连接中'
  })
  if (that.data.directFirstIsFail) {
    //直连失败，需要判断是否获取位置权限
    wx.getLocation({
      type: 'gcj02',
      complete: function (res) {
        console.warn('【-蓝牙直连-getLocation-res】', res);
        if (res.errMsg.indexOf('auth') != -1) {
          that.setData({
            loading_show: false,
            modal: {
              modal_show: true,
              title: '温馨提示',
              desc: '为了您能正常使用，请您授权小程序位置权限',
              desc_center: true,
              openSetting: true
            }
          })
        } else if (res.errMsg.indexOf('system') != -1) {
          that.setData({
            loading_show: false,
            modal: {
              modal_show: true,
              title: '温馨提示',
              desc: '请在系统设置中打开定位权限',
              desc_center: true,
              open_location_show: true,
              confirm: true
            }
          })
        } else {
          // directConTimeoutSeconds = 10;
          directConOpt(deviceName, statusCallback, timeout, isRetry, encryptValue, timeBytes, that);
        }
      }

    })
  } else {
    directConTimeoutSeconds = 15;
    timer_directCon_seconds = null;
    timer_directCon_seconds = setInterval(() => {
      if (directConTimeoutSeconds == 0) {
        clearInterval(timer_directCon_seconds);
        return;
      }
      directConTimeoutSeconds = directConTimeoutSeconds - 1;
    }, 1000)
    directConOpt(deviceName, statusCallback, timeout, isRetry, encryptValue, timeBytes, that);
  }

}

function directConOpt(deviceName, statusCallback, timeout, isRetry, encryptValue, timeBytes, that) {
  if (that.data.stopConnect) {//用户中断连接
    that.data.stopConnect = false;
    return;
  }
  wx.getConnectedBluetoothDevices({
    services: ['FEE7'],
    success: function (res) {
      console.warn('--连接中的设备', res);
      if (res.devices.length > 0) {
        return;
      } else {
        canDirectConOpt(deviceName, statusCallback, timeout, isRetry, encryptValue, timeBytes, that)
      }
    },
    fail: function () {
      canDirectConOpt(deviceName, statusCallback, timeout, isRetry, encryptValue, timeBytes, that)
    }
  })


}

function canDirectConOpt(deviceName, statusCallback, timeout, isRetry, encryptValue, timeBytes, that) {
  if (directConTimeoutSeconds == 0) {
    console.error("直连连接超时,请重试")
    //展示连接超时
    that.setData({
      loading_show: false,
      modal: {
        modal_show: true,
        desc: '连接超时，请关闭蓝牙再打开后重试',
        confirm: true
      }
    })
    getApp().sendLog('directConnect timeout', '', '');
    return;
  }
  console.warn("----start connect-------<>----####", deviceName)
  _that = that;
  obBleUninstall(that);
  that.data.curDevName = deviceName;
  getApp().globalData._that = that;
  setParams(statusCallback, that);
  openAdapterCount = 3;
  s = 3;

  _WXWriteUUID = '0000FEC7-0000-1000-8000-00805F9B34FB';
  _WXServiceUUID = '0000FEE7-0000-1000-8000-00805F9B34FB';
  var devId = that.data.wxDeviceId;
  _Device = {};
  _Device.deviceId = devId;
  console.log("device-->", _Device);

  wx.openBluetoothAdapter({
    success: function (res) {
      setTimeout(() => {
        startDiscovery(deviceName, statusCallback, timeout, isRetry, encryptValue, timeBytes, that);
      }, 200)
    },
    fail: function (res) {
      if (res.errCode == 10001 || res.errMsg.indexOf('not available') != -1) {
        showDialog("openBluetoothAdapter fail:" + JSON.stringify(res), Status.bleIsClosed, function () { });
      } else {
        that.data.directFirstIsFail = true;
        directConOpt(deviceName, statusCallback, timeout, isRetry, encryptValue, timeBytes, that);
      }
    }
  })
}

function startDiscovery(deviceName, statusCallback, timeout, isRetry, encryptValue, timeBytes, that) {
  var devId = that.data.wxDeviceId;
  wx.startBluetoothDevicesDiscovery({
    allowDuplicatesKey: true,
    success: function (res) {
      setTimeout(function () {
        wx.stopBluetoothDevicesDiscovery({
          success: function (res) { },
          complete: function (res) {
            //直接连接
            a.globalData.isConnecting = true;
            wx.createBLEConnection({
              // 这里的 deviceId 需要已经通过 createBLEConnection 与对应设备建立链接
              deviceId: devId,
              timeout: _CreateConnectionTimeoutSize,
              success(res) {
                console.log(res);
                a.globalData.isConnecting = false;
                notifyBLECharacteristicValueChange(deviceName, statusCallback, timeout, isRetry, encryptValue, timeBytes, that)
              },
              fail: function (res) {
                console.log("createCon", res)
                a.globalData.isConnecting = false;
                if (res.errMsg.indexOf('deviceId') != -1) {
                  that.setData({
                    loading_show: false,
                    modal: {
                      modal_show: true,
                      desc: '连接失败，请扫码重试',
                      confirm: true
                    }
                  })
                  return;
                } else if (res.errCode == -1 && res.errMsg.indexOf('already connect') != -1) {
                  notifyBLECharacteristicValueChange(deviceName, statusCallback, timeout, isRetry, encryptValue, timeBytes, that)
                  return;
                } else {
                  that.data.directFirstIsFail = true;
                  directConOpt(deviceName, statusCallback, timeout, isRetry, encryptValue, timeBytes, that);
                }
              }
            })

          },
          fail: function (res) {
            // that.data.directFirstIsFail = true;
            // directConOpt(deviceName, statusCallback, timeout, isRetry, encryptValue, timeBytes, that);
          }
        });
      }, 500)
    },
    fail: function (res) {
      if (res.errCode === 10000 && directConTimeoutSeconds > 0) {
        //蓝牙适配器未初始化，延时搜索
        setTimeout(() => {
          console.warn("adapter not init retry ");
          startDiscovery(deviceName, statusCallback, timeout, isRetry, encryptValue, timeBytes, that);
        }, 300);
      } else {
        //再重连直到15秒超时
        that.data.directFirstIsFail = true;
        directConOpt(deviceName, statusCallback, timeout, isRetry, encryptValue, timeBytes, that);
      }
    }
  });
}

function notifyBLECharacteristicValueChange(deviceName, statusCallback, timeout, isRetry, encryptValue, timeBytes, that) {
  var devId = that.data.wxDeviceId;
  wx.notifyBLECharacteristicValueChange({
    state: true, // 启用 notify 功能
    deviceId: devId,
    serviceId: '0000FEE7-0000-1000-8000-00805F9B34FB',
    characteristicId: '0000FEC8-0000-1000-8000-00805F9B34FB',
    success(res) {
      console.log('notifyBLECharacteristicValueChange success', res.errMsg)
    },
    complete: function (res) {
      onBLECharacteristicValueChange();
    },
    fail: function (res) {
      if (res.errCode === 10000 && directConTimeoutSeconds > 0) {
        //蓝牙适配器未初始化，延时搜索
        setTimeout(() => {
          console.warn("adapter not init retry ");
          notifyBLECharacteristicValueChange(deviceName, statusCallback, timeout, isRetry, encryptValue, timeBytes, that);
        }, 300);
      } else {
        //再重连直到15秒超时
        that.data.directFirstIsFail = true;
        directConOpt(deviceName, statusCallback, timeout, isRetry, encryptValue, timeBytes, that);
      }
    }
  })
}
/**
 * 安卓直连end
 */

module.exports.newConnect = newConnect
module.exports.directConnect = directConnect

module.exports.recordBroadcastMac = recordBroadcastMac
module.exports.setWriteUuid = setWriteUuid
module.exports.setDevice = setDevice
module.exports.setParams = setParams
module.exports.Status = Status
module.exports.disconnect = disconnect
module.exports.sendBroadcastConfCommand = sendBroadcastConfCommand
module.exports.send85Command = send85Command
module.exports.send95Command = send95Command
module.exports.send98Command = send98Command
module.exports.sendB0Command = sendB0Command
module.exports.send90Command = send90Command
module.exports.sendBaseCommand = sendBaseCommand
module.exports.setErrorCallback = setErrorCallback
module.exports.setConnectLogCall = setConnectLogCall
module.exports.setServerConfigInfo = setServerConfigInfo
module.exports.setConnectiTimeOut = setConnectiTimeOut
module.exports.setHomingDeviceServiceInfo = setHomingDeviceServiceInfo
module.exports.setCollectionServiceData = setCollectionServiceData
module.exports.transfer85To88 = transfer85To88
module.exports.getDriverVersion = getDriverVersion
module.exports.findDevStopDiscovery = findDevStopDiscovery
module.exports.scanBox = scanBox
module.exports.onBLECharacteristicValueChange = onBLECharacteristicValueChange
module.exports.ab2hex = ab2hex
module.exports.statusChanged = statusChanged
module.exports.startTimeout = startTimeout
module.exports.stopTimeout = stopTimeout
module.exports.handleDeviceData  = handleDeviceData 
module.exports.sendRstartCommand = sendRstartCommand